﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Xml.Linq;
using Dimok;
namespace Snatcher {
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class Window1 : Window {
		public Window1() {
			InitializeComponent();
		}

		private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
			var dc = Resources["ViewModel"] as ViewModel;
			dc.SaveDataContext.Execute(null);
		}
	}

	#region SaveDataContextCommand
	public class SaveDataContextCommand : ICommand {
		public readonly Action _executeMenthod;
		public SaveDataContextCommand(Action action) {
			_executeMenthod = action;
		}

		#region ICommand Members

		public bool CanExecute(object parameter) { return true; }

		public event EventHandler CanExecuteChanged;

		public void Execute(object parameter) {
			_executeMenthod();
		}

		#endregion
	}
	#endregion

	#region ConnectToBrowserCommand
	public class ConnectToBrowserCommand : ICommand {
		public readonly Action<string> _executeMenthod;
		public ConnectToBrowserCommand(Action<string> action) {
			_executeMenthod = action;
		}
		#region ICommand Members

		public bool CanExecute(object parameter) {
			return true;
		}

		public event EventHandler CanExecuteChanged;

		public void Execute(object parameter) {
			_executeMenthod(parameter + "");
		}

		#endregion
	}
	#endregion

	public class ViewModel : Dimok.Model {

		#region const
		const string VOX_FRAME_ID = "CenterRegion";
		const string VOX_STATUS_ID = "centerStatus";

		#endregion

		WatiN.Core.IE _ieVox = null;
		WatiN.Core.IE ieVox {
			get {
				if (_ieVox == null) {
					var title = WatiN.Core.Find.ByTitle(TitleVox);
					if (WatiN.Core.IE.Exists(title)) {
						_ieVox = WatiN.Core.IE.AttachToIE(title);
					} else _ieVox = new WatiN.Core.IE(AddressVox);
					_ieVox.AutoClose = false;
				}
				return _ieVox;
			}
		}

		#region ieMBC
		WatiN.Core.IE ieMBC(string id) {
			var title = WatiN.Core.Find.ByTitle(TitleMBC);
			var address = AddressMBC + "'" + id + "'";
			if (WatiN.Core.IE.Exists(title)) {
				var ie = WatiN.Core.IE.AttachToIE(title);
				ie.AutoClose = false;
				ie.GoTo(address);
				return ie;
			} else return new WatiN.Core.IE(AddressMBC + "'" + id + "'") { AutoClose = false };
		}
		#endregion

		#region Status
		string _status = "";
		public string Status {
			get { return _status; }
			set { 
				_status = value;
				RaisePropertyChanged("Status");
				RaisePropertyChanged("StatusColor");
			}
		}
		SolidColorBrush readyColor = new SolidColorBrush(Colors.DarkGreen);
		SolidColorBrush readyNotColor = new SolidColorBrush(Colors.DarkRed);
		public SolidColorBrush StatusColor { get { return Regex.IsMatch(Status, "^ready", RegexOptions.IgnoreCase) ? readyColor : readyNotColor; } }
		#endregion

		#region TitleVox
		string _titleVox = "Agent Control Panel";
		[DataMember]
		public string TitleVox {
			get { return _titleVox; }
			set { 
				_titleVox = value;
				RaisePropertyChanged("TitleVox");
			}
		}
		#endregion

		#region AddressVox
		string _addressVox = @"C:\Data\VS.2005\Dialer\Agent Control Panel.mht";
		[DataMember]
		public string AddressVox {
			get { return _addressVox; }
			set { 
				_addressVox = value;
				RaisePropertyChanged("AddressVox");
			}
		}
		#endregion

		#region TitleMBC
		string _titleMBC = "USIX Bridge";
		[DataMember]
		public string TitleMBC {
			get { return _titleMBC; }
			set {
				_titleMBC = value;
				RaisePropertyChanged("TitleMBC");
			}
		}
		#endregion

		#region AddressMBC
		string _addressMBC = "http://mbc/manager/USIX/USIXBridge.aspx?Filter=UsixID=";
		[DataMember]
		public string AddressMBC {
			get { return _addressMBC; }
			set { _addressMBC = value; }
		}
		#endregion

		public string StartText {
			get { return snatchTimer == null || !snatchTimer.IsEnabled ? "Start" : "Stop"; }
		}

		string _errorString = "";

		public string ErrorString {
			get { return _errorString; }
			set {
				_errorString = value;
				RaisePropertyChanged("ErrorString");
			}
		}
		string _accountNumber = "";

		public string AccountNumber {
			get { return _accountNumber; }
			set {
				if (_accountNumber == value) return; ;
				_accountNumber = value;
				RaisePropertyChanged("AccountNumber");
				ShowApplicant(Regex.Replace(AccountNumber, @"^\d", ""));
			}
		}

		#region SaveDataContext
		private SaveDataContextCommand saveDataContext;
		public ICommand SaveDataContext {
			get {
				if (saveDataContext == null)
					saveDataContext = new SaveDataContextCommand(() => {
						var x = new XElement("DataContext",
							GetType().GetProperties()
							.Where(p => p.GetCustomAttributes(false).Any(a=>a is DataMemberAttribute))
							.Select(p => new XAttribute(p.Name, p.GetValue(this, null))));
						System.IO.File.WriteAllText("DataContext.xml", x.ToString(SaveOptions.DisableFormatting));
					});
				return saveDataContext;
			}
		}
		#endregion

		#region ConnectToBrowser
		private ConnectToBrowserCommand connectToBrowser;
		public ICommand ConnectToBrowser {
			get {
				if (connectToBrowser == null)
					connectToBrowser = new ConnectToBrowserCommand(StartSnatching);
				return connectToBrowser;
			}
		}
		#endregion

		DispatcherTimer snatchTimer;
		void StartSnatching(string param) {
			if( snatchTimer == null)
				snatchTimer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Normal, GetApplicantID, Dispatcher.CurrentDispatcher);
			if (snatchTimer.IsEnabled) snatchTimer.Start();
			else snatchTimer.Stop();
			RaisePropertyChanged("StartText");
		}

		void GetApplicantID(object sender, EventArgs e) {
			try {
				//ShowApplicant("DA112132");
				//var frame = ie.Frame(VOX_FRAME_ID);
				var frames = ieVox.Frames.ToArray();
				if (frames.Length < 1) throw new Exception("No FRAMES founs in LiveVox page.");
				var frame = frames[0].Frame(VOX_FRAME_ID);
				ieVox.WaitForComplete();
				var span = ieVox.Frames.ToArray()[0].Span(VOX_STATUS_ID);
				if (!span.Exists) throw new WatiN.Core.Exceptions.ElementNotFoundException("SPAN", "ID=" + VOX_STATUS_ID, ieVox.Url);
				Status = span.Text + " : " + span.NextSibling;
				var accNumberPara = ieVox.Frames.ToArray()[0].Frame("CenterRegion").Para(WatiN.Core.Find.ByText(new Regex("^ACCOUNT NUMBER",RegexOptions.IgnoreCase)));
				if (!accNumberPara.Exists) throw new WatiN.Core.Exceptions.ElementNotFoundException("P", "Text starts with ACCOUNT NUMBER", ieVox.Url);
				AccountNumber = Regex.Match( accNumberPara.Text,@"\S+\s*$").Value;
			} catch (System.Runtime.InteropServices.InvalidComObjectException exc) {
				_ieVox.Dispose();
				_ieVox = null;
				ErrorString = exc.ToString();
			} catch (Exception exc) {
				ErrorString = exc.ToString();
			}
		}
		void ShowApplicant(string id) {
			using (var ie = ieMBC(id)) {
				return;
				try {
					var frame = ie.Frame(WatiN.Core.Find.ByName("frmContent"));
					var div = frame.Div("divMenuBar");
					if (!div.Exists) throw new WatiN.Core.Exceptions.ElementNotFoundException("DIV", "ID=divMenuBar", "");
					var span = div.Span(WatiN.Core.Find.By("innertext", "ID:"));
					if (!span.Exists) throw new WatiN.Core.Exceptions.ElementNotFoundException("SPAN", "innetText=ID:", "");
					var input = span.NextSibling as WatiN.Core.TextField;
					if (input == null) throw new WatiN.Core.Exceptions.ElementNotFoundException("INPUT", "ID:<INPUT/>", "");
					input.Value = id;
					span.Click();
				} catch (Exception exc) {
					ErrorString = exc.ToString();
				}
			}
			//.NextSibling.SetAttributeValue("value","DIMOK")		}
		}
		public ViewModel() {
			if( System.IO.File.Exists("DataContext.xml") )
				XDocument.Load("DataContext.xml")
					.Root.Attributes().ToList().
					ForEach(a => this.SetProperty(a.Name.LocalName, a.Value));
		}
		~ViewModel() {
			_ieVox.Dispose();
		}
	}
}
